home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MSJV7_2B.ARJ / UTILITY.C < prev    next >
C/C++ Source or Header  |  1992-03-01  |  18KB  |  606 lines

  1. /* 
  2.  * utility.c - general purpose utility routines
  3.  *
  4.  * Created by Microsoft Corporation.
  5.  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
  6.  *
  7.  */
  8.  
  9. //*** INCLUDES ****
  10.  
  11. #include <windows.h>
  12. #include <ole.h>
  13.  
  14. #include "global.h"
  15. #include "demorc.h"
  16. #include "utility.h"
  17. #include "object.h"
  18. #include "dialog.h"
  19.  
  20. FARPROC lpfnTimerProc = NULL;
  21. static  int iTimerID = 0;
  22. static  APPITEMPTR lpaItemHold;
  23.  
  24. /****************************************************************************
  25.  *  ErrorMessage()
  26.  *
  27.  *  Display a message box containing the specified string from the table.
  28.  *
  29.  *  id WORD       - Index into string table.
  30.  ***************************************************************************/
  31.  
  32. VOID FAR ErrorMessage(                 //* ENTRY:
  33.    WORD           id                   //* message ID
  34. ){                                     //* LOCAL:
  35.    char           sz[CBMESSAGEMAX];    //* string 
  36.    HWND           hwnd;                //* parent window handle
  37.  
  38.    if (IsWindow(hwndProp))
  39.       hwnd = hwndProp;
  40.    else if (IsWindow(hwndFrame))
  41.       hwnd = hwndFrame; 
  42.    else
  43.       return;
  44.  
  45.    LoadString(hInst, id, sz, CBMESSAGEMAX);
  46.    MessageBox(hwnd, sz, szAppName, MB_OK | MB_ICONEXCLAMATION);
  47.  
  48. }
  49.  
  50.  
  51. /****************************************************************************
  52.  *  Hourglass()
  53.  *
  54.  *  Put up or takes down the hourglass cursor as needed.
  55.  *
  56.  *  int  bToggle  - TRUE turns the hour glass on
  57.  *                  HG_OFF turn it off  
  58.  ***************************************************************************/
  59.  
  60. VOID FAR Hourglass(                    //* ENTRY:
  61.    BOOL           bOn                  //* hourglass on/off
  62. ){                                     //* LOCAL:
  63.    static HCURSOR hcurWait = NULL;     //* hourglass cursor
  64.    static HCURSOR hcurSaved;           //* old cursor
  65.    static         iCount = 0;
  66.  
  67.  
  68.    if (bOn)
  69.    {
  70.       iCount++;
  71.       if (!hcurWait) 
  72.          hcurWait = LoadCursor(NULL, IDC_WAIT);
  73.       if (!hcurSaved) 
  74.          hcurSaved = SetCursor(hcurWait);
  75.    }
  76.    else if (!bOn)
  77.    {  
  78.       if (--iCount < 0 )
  79.          iCount = 0;
  80.       else if (!iCount)
  81.       {
  82.          SetCursor(hcurSaved);
  83.          hcurSaved = NULL;
  84.       }
  85.    }
  86.  
  87. }
  88.  
  89.  
  90. /***************************************************************************
  91.  *  WaitForObject()
  92.  *
  93.  *  Dispatch messagee until the specified object is not busy. 
  94.  *  This allows asynchronous processing to occur.
  95.  *
  96.  *  lpObject    LPOLEOBJECT - pointer to object
  97.  **************************************************************************/
  98.  
  99. void FAR WaitForObject(                //* ENTRY:
  100.    APPITEMPTR    paItem                //* pointer to OLE object
  101. ){                                     //* LOCAL
  102.    int i = 0;
  103.  
  104.    while (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY)
  105.    {
  106.       if (!i)
  107.       {
  108.          ToggleBlockTimer(TRUE,paItem);//* set timer
  109.          i++;
  110.       }
  111.       ProcessMessage(hwndFrame, hAccTable);
  112.    }
  113.  
  114. }
  115.  
  116. /***************************************************************************
  117.  *  WaitForAllObjects()
  118.  *
  119.  *  Wait for all asynchronous operations to complete. 
  120.  **************************************************************************/
  121.  
  122. VOID FAR WaitForAllObjects(VOID)
  123. {
  124.  
  125.    while (cOleWait) 
  126.       ProcessMessage(hwndFrame, hAccTable) ;
  127.      
  128. }
  129.  
  130. /****************************************************************************
  131.  * ProcessMessage()
  132.  *
  133.  * Obtain and dispatch a message. Used when in a message dispatch loop. 
  134.  *
  135.  *  Returns BOOL - TRUE if message other than WM_QUIT retrieved
  136.  *                 FALSE if WM_QUIT retrieved.
  137.  ***************************************************************************/
  138.  
  139. BOOL FAR ProcessMessage(               //* ENTRY:
  140.    HWND           hwndFrame,           //* main window handle
  141.    HANDLE         hAccTable            //* accelerator table handle
  142. ){                                     //* LOCAL:
  143.    BOOL           fReturn;             //* return value
  144.    MSG            msg;                 //* message
  145.  
  146.    if (fReturn = GetMessage(&msg, NULL, NULL, NULL)) 
  147.    {
  148.       if (cOleWait || !TranslateAccelerator(hwndFrame, hAccTable, &msg)) 
  149.       {
  150.             TranslateMessage(&msg);
  151.             DispatchMessage(&msg); 
  152.       }
  153.    }
  154.    return fReturn;
  155.  
  156. }
  157.  
  158. /****************************************************************************
  159.  *  Dirty()
  160.  *
  161.  *  Keep track of weather modifications have been made 
  162.  *  to the document or not.
  163.  *
  164.  *  iAction - action type:
  165.  *            DOC_CLEAN set document clean flag true
  166.  *            DOC_DIRTY the opposite
  167.  *            DOC_UNDIRTY undo one dirty op
  168.  *            DOC_QUERY return present state
  169.  *
  170.  *  Returs int - present value of fDirty; 0 is clean.
  171.  ***************************************************************************/
  172.  
  173. int FAR Dirty(                         //* ENTRY:
  174.    int            iAction              //* see above comment
  175. ){                                     //* LOCAL:
  176.    static int     iDirty = 0;          //* dirty state >0 is dirty
  177.  
  178.    switch (iAction)
  179.    {
  180.       case DOC_CLEAN:
  181.          iDirty = 0;
  182.          break;
  183.       case DOC_DIRTY:
  184.          iDirty++;
  185.          break;
  186.       case DOC_UNDIRTY:
  187.          iDirty--;
  188.          break;
  189.       case DOC_QUERY:
  190.          break;
  191.    }
  192.    return(iDirty);
  193.  
  194. }
  195.  
  196. /***************************************************************************
  197.  *  ObjectsBusy()
  198.  *
  199.  *  This function enumerates the OLE objects in the current document 
  200.  *  and displays a message box stating whether an object is busy. 
  201.  *  This function calls  the DisplayBusyMessage() function which 
  202.  *  performs most of the work. This function is only used by the macro
  203.  *  BUSY_CHECK(), defined in object.h.
  204.  *
  205.  *  fSelectionOnly  BOOL -NOT USED?
  206.  *
  207.  *  BOOL - TRUE if one or more objects found to be busy
  208.  *             FALSE otherwise
  209.  *
  210.  ***************************************************************************/
  211.  
  212. BOOL FAR ObjectsBusy ()
  213. {
  214.    APPITEMPTR pItem;
  215.  
  216.    if (iTimerID)
  217.    {
  218.       RetryMessage(NULL,RD_CANCEL);
  219.       return TRUE;
  220.    }
  221.  
  222.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  223.       if (DisplayBusyMessage(pItem))
  224.          return TRUE;
  225.  
  226.    return FALSE;
  227.  
  228. }
  229.  
  230. /***************************************************************************
  231.  *  DisplayBusyMessage()
  232.  *
  233.  *  This function determines if an object is busy and displays 
  234.  *  a message box stating this status. 
  235.  *
  236.  *  Returns BOOL - TRUE if object is busy
  237.  **************************************************************************/
  238.  
  239. BOOL FAR DisplayBusyMessage (          //* ENTRY:
  240.    APPITEMPTR     paItem               //* application item pointer
  241. ){                                     //* LOCAL:
  242.     
  243.    if (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY) 
  244.    {
  245.       RetryMessage(paItem,RD_CANCEL);
  246.       return TRUE;    
  247.    }
  248.    return FALSE;
  249.  
  250. }
  251.  
  252. /***************************************************************************
  253.  * CreateNewUniqueName()
  254.  *
  255.  * Create a string name unique to this document. This is done by using the
  256.  * prefix string("OleDemo #") and appending a counter to the end of the 
  257.  * prefix string. The counter is incremented  whenever a new object is added. 
  258.  * String will be 14 bytes long.
  259.  *
  260.  * Return LPSTR - pointer to unique object name.
  261.  ***************************************************************************/
  262.  
  263. LPSTR FAR CreateNewUniqueName(         //* ENTRY:
  264.    LPSTR          lpstr                //* destination pointer
  265. ){
  266.  
  267.     wsprintf( lpstr, "%s%04d", OBJPREFIX, iObjectNumber++ );
  268.     return( lpstr );
  269.  
  270. }
  271.  
  272. /***************************************************************************
  273.  *  ValidateName()
  274.  *
  275.  *  This function ensures that the given object name is valid and unique.
  276.  *
  277.  *  Returns: BOOL - TRUE if object name valid
  278.  **************************************************************************/
  279.  
  280. BOOL FAR ValidateName(                 //* ENTRY:
  281.    LPSTR          lpstr                //* pointer to object name
  282. ){                                     //* LOCAL:
  283.    LPSTR          lp;                  //* worker string
  284.    int            n;
  285.                                        //* check for "OleDemo #" prefix
  286.    lp = OBJPREFIX;
  287.  
  288.    while( *lp ) 
  289.    {
  290.       if( *lpstr != *lp )
  291.          return( FALSE );
  292.  
  293.       lpstr++; lp++;
  294.    }
  295.                                        //* convert string number to int
  296.    for (n = 0 ; *lpstr ; n = n*10 + (*lpstr - '0'),lpstr++);
  297.  
  298.    if( n > 9999 )                      //* 9999 is largest legal number
  299.       return FALSE;
  300.  
  301.    if( iObjectNumber <= n)             //* Make count > than any current
  302.       iObjectNumber = n + 1;           //* object to ensure uniqueness
  303.  
  304.     return TRUE;
  305. }
  306.  
  307. /***************************************************************************
  308.  * FreeAppItem()
  309.  *
  310.  * Free application item structure and destroy the associated structure.
  311.  **************************************************************************/
  312.  
  313. VOID FAR FreeAppItem(                  //* ENTRY:
  314.    APPITEMPTR     pItem                //* pointer to application item
  315. ){                                     //* LOCAL:
  316.    HANDLE         hWork;               //* handle used to free
  317.    
  318.    if (pItem)
  319.    {                                   //* destroy the window
  320.       if (pItem->hwnd)
  321.          DestroyWindow(pItem->hwnd);
  322.  
  323.       hWork = LocalHandle((WORD)pItem);//* get handle from pointer
  324.  
  325.       if (pItem->aLinkName)
  326.          DeleteAtom(pItem->aLinkName);
  327.  
  328.       if (pItem->aServer)
  329.          DeleteAtom(pItem->aServer);
  330.  
  331.       LocalUnlock(hWork);
  332.       LocalFree(hWork);
  333.    }
  334.  
  335. }
  336.  
  337. /***************************************************************************
  338.  * SizeOfLinkData()
  339.  *
  340.  * Find the size of a linkdata string.
  341.  **************************************************************************/
  342.  
  343. LONG FAR SizeOfLinkData(               //* ENTRY:
  344.    LPSTR          lpData               //* pointer to link data
  345. ){                                     //* LOCAL:
  346.    LONG           lSize;               //* total size
  347.  
  348.    lSize = (LONG)lstrlen(lpData)+1;       //* get size of classname
  349.    lSize += (LONG)lstrlen(lpData+lSize)+1; //* get size of doc.
  350.    lSize += (LONG)lstrlen(lpData+lSize)+2;//* get size of item
  351.    return lSize;
  352.  
  353. }
  354.  
  355. /****************************************************************************
  356.  * ShowDoc()
  357.  *
  358.  * Display all the child windows associated with a document, or make all the
  359.  * child windows hidden.
  360.  ***************************************************************************/
  361.  
  362. VOID FAR ShowDoc(                      //* ENTRY:
  363.    LHCLIENTDOC    lhcDoc,              //* document handle
  364.    int            iShow                //* show/hide
  365. ){                                     //* LOCAL:
  366.    APPITEMPTR     pItem;               //* application item pointer
  367.    APPITEMPTR     pItemTop = NULL;
  368.  
  369.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  370.    {
  371.       if (pItem->lhcDoc == lhcDoc)
  372.       {
  373.          if (!pItemTop)
  374.             pItemTop = pItem;
  375.          ShowWindow(pItem->hwnd,(iShow ? SW_SHOW : SW_HIDE)); 
  376.          pItem->fVisible = (BOOL)iShow;
  377.       }
  378.    }
  379.    
  380.    if (pItemTop)
  381.       SetTopItem(pItemTop);
  382.  
  383. }           
  384.       
  385. /****************************************************************************
  386.  * GetNextActiveItem()
  387.  *
  388.  * Returns HWND - the next visible window. 
  389.  ***************************************************************************/
  390.  
  391. APPITEMPTR FAR GetNextActiveItem()
  392. {                                      //* LOCAL:
  393.    APPITEMPTR     pItem;               //* application item pointer
  394.  
  395.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  396.       if (pItem->fVisible)
  397.          break;
  398.  
  399.    return pItem;
  400.  
  401. }
  402.  
  403. /****************************************************************************
  404.  * GetTopItem()
  405.  ***************************************************************************/
  406.  
  407. APPITEMPTR FAR GetTopItem()
  408. {
  409.    HWND hwnd;
  410.  
  411.    if (hwnd = GetTopWindow(hwndFrame))
  412.       return ((APPITEMPTR)GetWindowWord(hwnd,0));
  413.    else
  414.       return NULL;
  415.  
  416. }
  417. /****************************************************************************
  418.  * GetNextItem()
  419.  ***************************************************************************/
  420.  
  421. APPITEMPTR FAR GetNextItem(            //* ENTRY:
  422.    APPITEMPTR     pItem                //* application item pointer
  423. ){                                     //* LOCAL:
  424.    HWND           hwnd;                //* next item window handle
  425.  
  426.    if (hwnd = GetNextWindow(pItem->hwnd, GW_HWNDNEXT))
  427.       return((APPITEMPTR)GetWindowWord(hwnd,0));
  428.    else
  429.       return NULL;
  430.  
  431. }
  432.  
  433. /****************************************************************************
  434.  * SetTopItem()
  435.  ***************************************************************************/
  436.  
  437. void FAR SetTopItem(
  438.    APPITEMPTR     pItem
  439. ){
  440.    APPITEMPTR     pLastItem;
  441.  
  442.    pLastItem = GetTopItem();
  443.    if (pLastItem && pLastItem != pItem)
  444.       SendMessage(pLastItem->hwnd,WM_NCACTIVATE, 0, 0L);
  445.  
  446.    if (!pItem)
  447.       return;
  448.  
  449.    if (pItem->fVisible)
  450.    {
  451.       BringWindowToTop(pItem->hwnd);
  452.       SendMessage(pItem->hwnd,WM_NCACTIVATE, 1, 0L);
  453.    }
  454.  
  455. }
  456.  
  457. /***************************************************************************
  458.  * ReallocLinkData()
  459.  *
  460.  * Reallocate link data in order to avoid creating lots and lots of global
  461.  * memory thunks.
  462.  **************************************************************************/
  463.  
  464. BOOL FAR ReallocLinkData(              //* ENTRY:
  465.    APPITEMPTR     pItem,               //* application item pointer
  466.    long           lSize                //* new link data size
  467. ){                                     //* LOCAL:
  468.    HANDLE         handle;              //* temporary memory handle
  469.  
  470.    handle = (HANDLE)GlobalHandle(HIWORD(pItem->lpLinkData));
  471.    GlobalUnlock(handle);
  472.  
  473.    if (!(pItem->lpLinkData = GlobalLock(GlobalReAlloc(handle, lSize, NULL)))) 
  474.    {
  475.       ErrorMessage(E_FAILED_TO_ALLOC); 
  476.       return FALSE;
  477.    }
  478.  
  479.    return TRUE;
  480.  
  481. }
  482.  
  483. /***************************************************************************
  484.  * AllocLinkData()
  485.  *
  486.  * Allocate link data space.
  487.  **************************************************************************/
  488.  
  489. BOOL FAR AllocLinkData(                //* ENTRY:
  490.    APPITEMPTR     pItem,               //* application item pointer
  491.    long           lSize                //* link data size
  492. ){
  493.  
  494.    if (!(pItem->lpLinkData = GlobalLock(
  495.          GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT ,lSize)
  496.       )))
  497.    {
  498.       ErrorMessage(E_FAILED_TO_ALLOC);
  499.       return FALSE;
  500.    }
  501.  
  502.    return TRUE;
  503. }
  504.  
  505. /***************************************************************************
  506.  * FreeLinkData()
  507.  *
  508.  * Free the space associated with a linkdata pointer.
  509.  **************************************************************************/
  510.  
  511. void FAR FreeLinkData(                 //* ENTRY:
  512.    LPSTR          lpLinkData           //* pointer to linkdata
  513. ){                                     //* LOCAL:
  514.    HANDLE         handle;              //* temporary memory handle
  515.  
  516.    if (lpLinkData)
  517.    {
  518.       handle = (HANDLE)GlobalHandle(HIWORD(lpLinkData));
  519.       GlobalUnlock(handle);
  520.       GlobalFree(handle);
  521.    }
  522. }
  523.  
  524. /****************************************************************************
  525.  * ShowNewWindow()
  526.  *
  527.  * Show a new application item window.
  528.  ***************************************************************************/
  529.  
  530. void FAR ShowNewWindow(                //* ENTRY:
  531.    APPITEMPTR     pItem
  532. ){
  533.  
  534.    if (pItem->fVisible)
  535.    {
  536.       pItem->fNew = TRUE;
  537.       SetTopItem(pItem);
  538.       ShowWindow(pItem->hwnd,SW_SHOW);
  539.    }
  540.    else
  541.       ObjDelete(pItem,DELETE);
  542.  
  543. }
  544.  
  545. /****************************************************************************
  546.  * UnqualifyPath()
  547.  *
  548.  * return pointer to unqualified path name.
  549.  ***************************************************************************/
  550.  
  551. PSTR FAR UnqualifyPath(PSTR pPath)
  552. {
  553.    PSTR pReturn;
  554.  
  555.    for (pReturn = pPath; *pPath; pPath++)  
  556.       if (*pPath == ':' || *pPath == '\\')
  557.          pReturn = pPath+1;
  558.  
  559.    return pReturn;
  560.  
  561. }
  562.  
  563. /****************************************************************************
  564.  * StartBlockTimer()
  565.  *
  566.  * Toggle a timer used to check for blocked servers.
  567.  ***************************************************************************/
  568.  
  569. void FAR ToggleBlockTimer(BOOL bSet, APPITEMPTR lpaItem)
  570. {     
  571.    lpaItemHold = lpaItem;
  572.  
  573.    if (bSet && !iTimerID)
  574.    {
  575.       if (!lpfnTimerProc)
  576.          lpfnTimerProc = MakeProcInstance(fnTimerBlockProc, hInst);
  577.       iTimerID = SetTimer(hwndFrame,1, 3000,lpfnTimerProc);
  578.    }
  579.    else if (iTimerID)
  580.    {
  581.       KillTimer(hwndFrame,1);
  582.       iTimerID = 0;
  583.    }
  584.  
  585. }
  586.  
  587. /****************************************************************************
  588.  *  fnTimerBlockProc()
  589.  *
  590.  *  Timer callback procedure
  591.  ***************************************************************************/
  592.  
  593. BOOL FAR PASCAL fnTimerBlockProc(      //* ENTRY: 
  594.    HWND     hWnd,
  595.    WORD     wMsg,
  596.    int      iTimerID,
  597.    DWORD    dwTime
  598. ){
  599.  
  600.    if (!hRetry)
  601.       RetryMessage(lpaItemHold, RD_RETRY | RD_CANCEL);
  602.  
  603. }
  604.  
  605.  
  606.